package com.yuanshi.food.common.utils;

import cn.hutool.core.date.DatePattern;
import com.yuanshi.food.common.consts.GlobalConst;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

/**
 * redis标识
 *
 * @author wcy
 * @date 2024/12/02
 */
@Component
public class RedisIdWorkerUtil {
    public static final int CODE_MAX_DIGIT = 10;
    /**
     * 序列号的位数
     */
    private static final int COUNT_BITS = 32;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    public String nextId(String businessCode) {
        // 确保businessCode长度不超过10位
        if (businessCode.length() > CODE_MAX_DIGIT) {
            throw new IllegalArgumentException("业务编码不能大于10位");
        }

        String key = GlobalConst.GLOBAL_ID_PREFIX + businessCode + GlobalConst.GLOBAL_ID_SUFFIX;
        // 设置过期时间
        this.setExpireAt(key);

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DatePattern.PURE_DATETIME_PATTERN);
        String formattedDateTime = LocalDateTime.now().format(formatter);

        // 使用Redis的INCR命令自增并获取当前值，保证了并发下的唯一性

        Long increment = stringRedisTemplate.opsForValue().increment(key);

        // 计算businessCode需要补全的字符数
        int paddingLength = COUNT_BITS - formattedDateTime.length() - businessCode.length();

        String formattedIncrement = String.format("%0" + paddingLength + "d", increment);

        // 组合所有部分
        return businessCode + formattedDateTime + formattedIncrement;
    }

    /**
     * 初始化
     */
    public void setExpireAt(String key) {
        // 检查键是否存在
        Boolean hasKey = stringRedisTemplate.hasKey(key);
        if (hasKey) {
            // 如果键存在，说明已经是今天的，直接返回
            return;
        }

        // 设置今天的00:00:00
        LocalDate today = LocalDate.now();
        ZonedDateTime expireTime = today.plusDays(1).atStartOfDay(ZoneId.systemDefault());

        // 设置键在明天的00:00:00过期
        stringRedisTemplate.expireAt(key, expireTime.toInstant());

      /*  // 设置初始值为0
        stringRedisTemplate.opsForValue().setIfAbsent(key, "0");*/
    }
}



